import { computed, Ref, ref } from "vue";
import { debounce } from "lodash-es";

declare interface UseVirtualListProp {
  itemWidth: number;
  itemHeight: number;
  extraList: any[];
  rowCount: number;
}

const useVirtualList = <T = any>(list: Ref<T[]>, option: UseVirtualListProp) => {
  const cardWidth = option.itemWidth;
  const cardHeight = option.itemHeight;
  const rowWidth = ref<number>(0);
  const height = ref<number>(700);
  const virtualListRef = ref<HTMLElement>();
  // 一行卡片数量
  const rowCount = computed(() => {
    if (option.rowCount > 0) {
      return option.rowCount;
    }
    const minItemMargin = 20; // 最小卡片间隔
    const count = Math.floor((rowWidth.value - 40) / cardWidth) < 1 ? 1 : Math.floor((rowWidth.value - 40) / cardWidth); // 预估数量
    const realWidth = cardWidth * count + (count - 1) * minItemMargin + 40;
    return realWidth > rowWidth.value ? (count - 1 < 1 ? 1 : count - 1) : count;
  });
  // 预估视窗范围内显示行数
  const columnCount = computed(() => {
    return Math.ceil(height.value / (cardHeight + 20));
  });
  // 多行list
  const calcList = computed(() => {
    const res: any[] = [];
    if (!rowCount.value) return res;
    let index = 0;
    [...option.extraList, ...list.value].forEach((item: any, idx: number) => {
      if (!res[index]) {
        res[index] = [item];
      } else {
        res[index].push(item);
      }
      if (idx % rowCount.value === rowCount.value - 1) {
        index++;
      }
    });
    return res;
  });

  const resizeHandler = () => {
    height.value = virtualListRef.value?.clientHeight || 0;
    rowWidth.value = virtualListRef.value?.clientWidth || 0;
  };

  const resize = debounce(() => {
    resizeHandler();
  }, 200);

  return {
    rowCount,
    columnCount,
    calcList,
    virtualList: virtualListRef,
    resize,
    height,
  };
};

export default useVirtualList;
